编程导航Java 基础话题讨论

Java 基础

22 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

jsp+servlet做的超市商品管理系统

# 超市商品管理系统 ## 项目介绍 这是一个基于JavaWeb技术栈开发的超市商品管理系统,采用传统的MVC架构模式,使用Servlet作为控制器,JSP作为视图层,通过JDBC进行数据库操作。系统提供了商品管理和类别管理的基本功能,并实现了基于角色的访问控制。 ## 技术栈 - 后端:JavaWeb (Servlet + JSP) - 数据库:MySQL 5.7 - 前端:原生JavaScript + CSS - 连接池:JDBC直连 - 项目管理:Eclipse IDE ## 系统特点 1. **用户权限管理** - 支持用户注册和登录功能 - 实现了基于角色的访问控制(RBAC) - 区分普通用户和管理员权限 2. **商品管理功能** - 商品的增删改查操作 - 支持按类别管理商品 - 用户只能管理自己添加的商品 - 管理员可以查看所有商品 3. **类别管理功能** - 商品类别的增删改查操作 - 仅管理员可以管理类别 4. **界面设计** - 清晰的布局结构(header、left menu、content、footer) - 响应式设计,适配不同屏幕尺寸 - 统一的页面风格和操作体验 ## 项目结构 ``` supermarket/ ├── WebContent/ # Web资源目录 │ ├── WEB-INF/ # Web配置目录 │ │ └── web.xml # Web应用配置文件 │ ├── css/ # 样式文件 │ │ └── style.css # 全局样式 │ ├── login.jsp # 登录页面 │ ├── register.jsp # 注册页面 │ ├── product_list.jsp # 商品列表页面 │ ├── product_form.jsp # 商品编辑页面 │ ├── category_list.jsp # 类别列表页面 │ └── category_form.jsp # 类别编辑页面 ├── src/ # Java源代码目录 │ └── com/supermarket/ │ ├── entity/ # 实体类 │ │ ├── User.java │ │ ├── Product.java │ │ └── Category.java │ ├── dao/ # 数据访问层 │ │ ├── UserDao.java │ │ ├── ProductDao.java │ │ └── CategoryDao.java │ ├── servlet/ # 控制器层 │ │ ├── UserServlet.java │ │ ├── ProductServlet.java │ │ └── CategoryServlet.java │ └── util/ # 工具类 │ └── DBUtil.java # 数据库连接工具 └── supermarket.sql # 数据库脚本 ``` ## 代码特点 1. **规范的代码组织** - 采用标准的MVC分层架构 - 清晰的包结构和命名规范 - 统一的编码风格 2. **安全性考虑** - 登录状态验证 - SQL注入防护 - 权限检查机制 3. **用户体验优化** - 表单验证 - 友好的错误提示 - 操作确认提示 4. **代码复用** - 通用的数据库连接工具 - 统一的页面布局 - 可重用的CSS样式 ## 部署说明 1. 创建MySQL数据库,执行`supermarket.sql`脚本 2. 配置`DBUtil.java`中的数据库连接信息 3. 使用Eclipse导入项目 4. 配置Tomcat服务器 5. 部署运行项目 ## 注意事项 1. 请确保MySQL 5.7已正确安装并运行 2. 数据库字符集使用utf8mb4 3. 请根据实际情况修改数据库连接配置 4. 建议使用Eclipse IDE进行开发和调试 <img src="https://pic.code-nav.cn/post_picture/1900441785166540802/4TIgDP3KOcqrUDbH.png" alt="1.png" width="395px" /> <img src="https://pic.code-nav.cn/post_picture/1900441785166540802/dvgILY6Yay2Ar5Xo.png" alt="2.png" width="348px" /> <img src="https://pic.code-nav.cn/post_picture/1900441785166540802/byHxr23xx6r2YHE0.webp" alt="3.png" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1900441785166540802/eRFXTkkgdnnjK1Bn.webp" alt="4.png" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1900441785166540802/37NlR5YErZIGKvFq.webp" alt="5.png" width="100%" /> <img src="https://pic.code-nav.cn/post_picture/1900441785166540802/5g564pNy9VWujayh.webp" alt="6.png" width="100%" />

话两天时间看完了核心卷一的重点部分 接下来就是刷题啦 奥里给!!

lambda表达式

@Test public void test() { sendMessage((name, Mr) -> { System.out.println("send message to email " + name + " " + Mr); return "success"; }); } private void sendMessage(Message message) { String msg = message.send("lihua" , "Mr"); System.out.println(msg); } ##### 接口 ` @FunctionalInterface public interface Message { public String send(String name,String Mr); }` ##### 定义: 1. 函数式接口:只有一个抽象方法的接口 Functional Interface 2. lambda表达式:Lambda Expressions 3. 抽象方法:Abstract Method ##### 写法: 1. () -> {} 2. (参数) -> {方法体} ##### 线程的实现 `@Test public void test1(){ new Thread(()-> System.out.println("new Thread")).start(); }`

各位大佬们好,我刚刚毕业,上岸了211电子信息,本科期间有计算机基础,自己学习了javase、mysql、springboot+vue的相关前后端开发等知识,目前的问题是从0到1开发一个系统很困难,但是由1拓展自己能做到,看得懂业务流程但是自己独立构建非常吃力,想趁着暑假学习一下,望各位大佬指点迷津。`(*>﹏<*)′

Java -Spring-boot

## Spring-Boot ### 1. Spring-Boot简介 Spring-Boot是Spring官方提供的一个快速开发脚手架,可以基于Spring-Boot快速开发单个微服务。 使用目的:简化Spring应用的初始搭建以及开发过程。如配置文件的配置,繁琐的依赖配置等。 ### 2. Spring-Boot特点 1. 独立运行的Spring项目 2. 内嵌Tomcat、Jetty或Undertow,不需要部署WAR文件 3. 提供运行时的应用监控 4. 提供starter简化Maven配置 5. 自动配置Spring ### 3.AppConfig.java 配置类 1. @Configuration:声明当前类是一个配置类,相当于Spring配置的xml文件 2. @Bean:声明在方法上,将方法的返回值加入Bean容器,相当于Spring配置的<bean>标签 2.1 @Bean(name="user"):指定Bean的名称,如果不指定,Bean的名称默认为方法名 2.2 @Bean(name="user",initMethod="init",destroyMethod="destroy"):指定Bean的初始化方法和销毁方法 2.3 关联其他Bean: 3. @ComponentScan:自动扫描包,相当于Spring配置的<context:component-scan>标签 ```java // 方式一: 调用方法注入 关联的bean @Bean public User user(){ return new User(); } @Bean public UserService userService(){ UserService userService = new UserService(); userService.setUser(user()); return userService; } // 方式二:通过方法形参注入 关联的bean @Bean public UserService userService(User user){ UserService userService = new UserService(); userService.setUser(user); return userService; } ``` ### 4.测试类Junit4和Junit5 ```java // Junit4 @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = AppConfig.class) // Junit5 @SpringBootTest(classes = AppConfig.class) ``` ### 5.主配置中导入其他配置类或者配置文件 ```java // 方式一:通过@Import注解导入其他配置类 @Configuration @Import({AppConfig2.class,AppConfig3.class}) // 方式二:通过@ImportResource注解导入其他配置文件 @Configuration @ImportResource("classpath:applicationContext.xml") // 方式三:通过@PropertySource注解导入其他配置文件 @Configuration @PropertySource("classpath:jdbc.properties") ``` ### 6.配置文件的优先级 `properties`文件的优先级高于`yml`文件而以下四个位置的配置文件优先级高低顺序如下: 1. 项目根目录下的config文件夹 2. 项目根目录下 3. classpath下的config文件夹 4. classpath下 ### 7.读取配置文件(三种方式) ```java // 方式一:通过@Value注解读取配置文件 @Value("${name}") private String name; // 方式二:通过Environment读取配置文件 @Autowired private Environment env; env.getProperty("name"); // 方式三:通过@ConfigurationProperties注解读取配置文件 @ConfigurationProperties(prefix = "user") ``` ## Spring-Boot 集成ssm ### 1. Spring-Boot集成Mybatis 1. 导入依赖 ```xml <!-- Spring-Boot集成Mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> ``` 2. 配置数据源 ```yml spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 123456 ``` 3. 配置Mybatis ```yml mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.demo.entity ``` 4. 编写Mapper接口和Mapper.xml文件 ```java // Mapper接口 public interface UserMapper { List<User> findAll(); } // Mapper.xml文件 <mapper namespace="com.example.demo.mapper.UserMapper"> <select id="findAll" resultType="com.example.demo.entity.User"> select * from user </select> </mapper> ``` 5.使用PageHelper分页插件 ```xml <!-- 使用PageHelper分页插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> </dependency> ``` ### 2. Spring-Boot集成SpringMVC 1. 导入依赖 ```xml <!-- Spring-Boot集成SpringMVC --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 2. 配置SpringMVC ```java // 配置类 @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); } } // 静态资源配置 spring: mvc: static-path-pattern: /static/** static-locations: classpath:/static/ ``` 3. 编写Controller ```java @Controller public class UserController { @Autowired private UserService userService; @RequestMapping("/findAll") public String findAll(Model model){ List<User> users = userService.findAll(); model.addAttribute("users",users); return "userList"; } } ``` ### 3. 事务管理 1. 导入依赖 ```xml <!-- 事务管理 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> ``` 2. 配置事务管理器 ```java // 配置类 @Configuration public class TransactionConfig { @Autowired private DataSource dataSource; @Bean public DataSourceTransactionManager transactionManager(){ return new DataSourceTransactionManager(dataSource); } } ``` ### 4.统一异常处理 1. 编写异常处理类 ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public String exceptionHandler(Exception e, Model model){ model.addAttribute("msg",e.getMessage()); return "error"; } } ``` 2. 拦截器配置 ```java // 配置类 @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); } } ``` ### 5. 日志管理 1. Slf4j日志 2. 使用方式 ```xml // 方式一:直接使用 private static final Logger logger = LoggerFactory.getLogger(UserController.class); // 方式二:使用注解 @Slf4j ``` 3. 日志级别 ```xml # 日志级别 warn info debug error ``` 4.5、Logback 配置文件的使用 ```xml <?xml version="1.0" encoding="UTF-8"?> <!-- scan:开启日志框架的热部署,默认值 true 表示开启 scanPeriod:热部署的频率,默认值 60 second debug:设置输出框架内部的日志,默认值 false --> <configuration scan="true" scanPeriod="60 second" debug="false"> <property name="appName" value="springboot demo" /> <contextName>${appName}</contextName> <!-- appender:日志输出对象,配置不同的类拥有不同的功能 ch.qos.logback.core.ConsoleAppender:日志输出到控制台 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd-HH:mm:ss} %level [%thread]-%logger{35} >> %msg %n</pattern>      </encoder>    </appender> <!-- ch.qos.logback.core.FileAppender:日志输出到文件中 <appender name="fileAppender" class="ch.qos.logback.core.FileAppender"> <encoder> <pattern>%-4relative [%thread] %level %logger{35} - %msg %n</pattern>    </encoder> <append>true</append> <file>mylog.log</file>    </appender> --> <!-- root 是项目通用的 logger,一般情况下都是使用 root 配置的日志输出 level:按照级别输出日志,日志级别,级别越高,输出的内容越少 -->    <root level="info"> <appender-ref ref="STDOUT" /> </root> <!-- 自定义的 logger,用于专门输出特定包中打印的日志 <logger name="cn.wolfcode.crm.mapper" level="trace"> </logger> --> </configuration> ``` ### 6. 修改banner 1. 在src/main/resources目录下新建banner.txt文件 ### 7. 热部署 1. 导入依赖 ```xml <!-- 热部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> ``` 2. 配置文件 ```yml # 热部署 spring: devtools: restart: enabled: true ``` ### 8. 自动配置 推荐文章: https://blog.csdn.net/qq_41805567/article/details/129111183

MyBatis-day-03 和 Maven 构建Java SE 项目

## MyBatis ### 一对多查询 单向多对多之额外 SQL 查询 根据 id 查询学生,并查询其老师。 需要添加 Mapper 接口 和 Mapper XML StudentMapper 接口 ```java public interface StudentMapper { Student get(Long id); } ``` StudentMapper.xml 文件 ```xml <resultMap type="Student" id="baseResultMap"> <id column="id" property="id"/> <result column="name" property="name"/> <!-- 关联属性,让 MyBatis 发额外 SQL --> <collection select="cn.wolfcode.mapper.TeacherMapper.queryByStudentId" column="id" property="teachers"/> </resultMap> <select id="get" resultMap="baseResultMap"> SELECT id, name FROM student WHERE id = #{id} </select> ``` TeacherMapper ```java package xxx.xxx.mapper; public interface queryByStudentId { Teacher get(Long id); } ``` TeacherMapper.xml 文件 ```xml <select id="queryByStudentId" resultType="Teacher"> SELECT t.id, t.name FROM teacher_student ts JOIN teacher t ON ts.teacher_id = t.id WHERE ts.student_id = #{studentId} </select> ``` 单元测试方法 ```java public class Many2oneTest { @Test public void testGet() throws Exception { SqlSession session = MyBatisUtil.getSession(); StudentMapper studentMapper = session.getMapper(StudentMapper.class); Student student = studentMapper.get(2L); System.out.println(student); session.close(); } } ``` ### 多对多查询 多对多映射关系 什么是多对多关系: 一对多关系就是表A中一条数据对应表B中的多条数据,例如,用户和订单之间的关系,一个用户可以有多个订单信息。 在mybatis中,与一对多映射一致,我们通过resultMap元素的子元素 `collection`来进行处理。 `需要注意的是:在一对多映射和多对多映射中,collection 元素属行中使用的是ofType属性来指定实体对象,而不是使用JavaType属性。` #### resultType 作用:将查询结果按照sql列名pojo属性名一致性映射到pojo中。 场合:常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。 resultMap 使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。 #### association: 作用:将关联查询信息映射到一个pojo对象中。 场合:为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。 使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。 #### collection: 作用:将关联查询信息映射到一个list集合中。 场合:为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块及模块下的菜单,可使用collection将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的作的目的也是方便对查询结果集进行遍历查询。如果使用resultType无法将查询结果映射到list集合中。 ## Maven maven 导入的jar包具有传递性,会自动导入该jar包需要的其他jar包 ### 安装Maven及配置相关文件,环境变量 ### 安装 访问 Maven 的官方网站:https://maven.apache.org/。 下载 Maven 的二进制发行版(Binary zip archive),选择最新版本并下载。 解压下载的二进制发行版到你选择的安装目录,例如 C:\Program Files\apache-maven-3.x.x(Windows)或 /usr/local/apache-maven-3.x.x(Linux/Mac) ### 配置环境变量 3. 右键点击 "此电脑"(或 "计算机"),然后选择 "属性"。 4. 在左侧面板中,点击 "高级系统设置"。 6. 在 "系统属性" 对话框中,点击 "环境变量" 按钮。 8. 在 "系统变量" 部分,找到 "Path" 变量,然后点击 "编辑"。 10. 在 "编辑环境变量" 对话框中,点击 "新建",并添加 Maven 的 bin 目录路径,例如 C:\Program Files\apache-maven-3.x.x\bin。 12. 点击 "确定" 关闭所有对话框。 ### 配置第三方中央仓库 在maven 安装目录下打开 `settings.xml` 文件。 在` <repositories> `元素中,你可以配置自定义的仓库。 ```xml <repositories> <repository> <id>myrepository</id> <url>http://your-custom-repository-url.com</url> </repository> </repositories> 这里,<id> 是自定义仓库的唯一标识符,<url> 是仓库的地址。你可以添加多个自定义仓库。 ``` 保存`settings.xml `文件。 ### 在IDEA中使用Maven 构建JAVA SE 项目 1. 打开 IntelliJ IDEA。 3. 创建一个新的 Java 项目或打开现有的项目。 5. 在项目的根目录中,你可以看到一个 pom.xml 文件,这是 Maven 项目的配置文件。确保该文件存在。 7. 打开 IntelliJ IDEA 的项目设置: 9. 在 Windows 上,点击 "File" > "Settings"。 11. 在左侧面板中,选择 "Build, Execution, Deployment"(构建、执行、部署)。 13. 在右侧窗格中,选择 "Build Tools"(构建工具)下的 "Maven"。 15. 在 "Maven home directory"(Maven 安装目录)字段中,选择 Maven 安装的目录,例如 C:\Program Files\apache-maven-3.x.x(Windows)或 /usr/local/apache-maven-3.x.x(Linux/Mac)。 17. 点击 "Apply" 和 "OK" 以保存设置。 19. IntelliJ IDEA 现在将使用 Maven 来构建和管理你的 Java 项目。 21. 你可以在 IntelliJ IDEA 的 Maven 工具窗口中执行 Maven 构建任务,例如 clean, install 等。打开 Maven 工具窗口的方式是点击底部的 "Maven" 标签或在 "View" > "Tool Windows" 中选择 "Maven"。

JAVA 框架阶段 常见报错信息及解决思路( 持续更新中)

# JDBC | 错误信息 | 可能的原因 | 解决方案 | | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | | `java.sql.SQLException: No suitable driver found` | 未加载正确的数据库驱动程序 | 1. 确保你已经导入了正确的数据库驱动程序库(如MySQL、PostgreSQL等)。 2. 使用 `Class.forName("com.mysql.jdbc.Driver");` 或者 `DriverManager.registerDriver(new com.mysql.jdbc.Driver());` 来注册数据库驱动。 | | `java.sql.SQLException: Connection refused` | 数据库服务器拒绝连接请求 | 1. 确保数据库服务器正在运行并监听正确的端口。 2. 检查数据库连接字符串中的主机名和端口是否正确。 3. 防火墙或网络问题可能导致连接被拒绝,需要检查网络配置。 | | `java.sql.SQLException: Access denied for user` | 用户没有权限连接到数据库 | 1. 确保用户名和密码正确。 2. 确保数据库用户有访问指定数据库的权限。 3. 检查数据库服务器的访问控制列表(ACL)配置。 | | `java.sql.SQLException: Invalid column index` | 使用了无效的列索引 | 1. 确保你在查询结果集中使用了正确的列索引。 2. 使用列的名称而不是索引来访问列数据。 | | `java.sql.SQLException: ResultSet is closed` | 尝试访问已关闭的结果集 | 1. 确保在结果集关闭之前完成了所有操作。 2. 避免在连接关闭后尝试访问结果集。 | | `java.sql.SQLException: Duplicate entry` | 尝试插入重复的数据 | 1. 在插入之前检查数据是否已经存在。 2. 使用唯一约束来防止重复数据插入。 | | `java.sql.SQLException: Timeout expired` | 操作超时 | 1. 增加操作的超时时间。 2. 优化查询或操作以减少执行时间。 | # MyBatis | 错误信息 | 可能的原因 | 解决方案 | | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | | `org.apache.ibatis.exceptions.PersistenceException: Error querying database` | SQL查询失败 | 1. 检查SQL语句是否正确。 2. 检查数据库连接是否正常。 3. 查看数据库日志以获取更多信息。 | | `org.apache.ibatis.binding.BindingException: Mapper method 'XXXX' not found` | 找不到Mapper接口中的方法 | 1. 确保Mapper接口中的方法名称与XML配置文件中的一致。 2. 检查Mapper接口所在的包路径是否正确。 | | `org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration` | XML配置文件中存在错误 | 1. 检查XML配置文件中的语法错误。 2. 确保XML配置文件的路径和名称正确。 | | `org.apache.ibatis.executor.ExecutorException: Cannot open Connection` | 无法打开数据库连接 | 1. 确保数据库服务器正在运行。 2. 检查数据库连接字符串和认证信息是否正确。 3. 检查数据库驱动是否正确配置。 | | `org.apache.ibatis.exceptions.TooManyResultsException: Expected one result` | 预期查询返回一条结果,但返回多条结果 | 1. 修改查询条件以确保只返回一条结果。 2. 使用 `SELECT ... LIMIT 1` 或类似的方法来限制结果数量。 | | `org.apache.ibatis.transaction.TransactionException: Transaction is not active` | 事务不活跃 | 1. 确保在事务中正确使用 `SqlSession` 对象。 2. 确保事务的提交和回滚操作正确执行。 | | `org.apache.ibatis.type.TypeException: Could not resolve type alias` | 类型别名无法解析 | 1. 检查XML配置文件中的类型别名是否正确。 2. 确保自定义类型处理器注册正确。 | | `org.apache.ibatis.parsing.ParsingException: Property 'XXXX' not found in XXXX` | 未找到属性 | 1. 确保在SQL语句中使用的属性名称存在于对应的Java对象中。 2. 检查属性名称的拼写和大小写。 | | `org.apache.ibatis.exceptions.PersistenceException: Error updating database` | 数据库更新操作失败 | 1. 检查SQL语句是否正确。 2. 确保数据库连接正常。 3. 查看数据库错误日志以获取更多信息。 | | `org.apache.ibatis.builder.IncompleteElementException: Could not find a statement` | 找不到指定的 SQL 语句 | 1. 确保在 XML 配置文件中定义了正确的 SQL 语句。 2. 检查 SQL 语句的命名空间是否正确。 | | `org.apache.ibatis.exceptions.PersistenceException: Error deleting database` | 数据库删除操作失败 | 1. 检查 SQL 语句是否正确。 2. 确保数据库连接正常。 3. 查看数据库错误日志以获取更多信息。 | | `org.apache.ibatis.session.SqlSessionException: Error closing session` | 关闭 SqlSession 时出错 | 1. 确保在使用完 SqlSession 后调用了 `close` 方法。 2. 检查是否有未提交的事务。 | | `org.apache.ibatis.executor.ExecutorException: Error updating database` | 数据库更新操作失败 | 1. 检查 SQL 语句是否正确。 2. 检查数据库连接是否正常。 3. 查看数据库错误日志以获取更多信息。 | | `org.apache.ibatis.binding.BindingException: Invalid bound statement` | 无效的绑定语句 | 1. 检查是否在 XML 配置文件中绑定了正确的语句。 2. 确保语句的命名空间和 ID 正确。 | | `org.apache.ibatis.cache.CacheException: Error serializing object` | 对象序列化错误 | 1. 确保对象及其关联的类都可序列化。 2. 检查对象是否有不可序列化的成员变量。 | | `org.apache.ibatis.exceptions.PersistenceException: Error loading class` | 加载类失败 | 1. 确保在 XML 配置文件中使用的类路径正确。 2. 检查类是否存在和可访问。 | | `org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'XXXX' from result set` | 从结果集获取列失败 | 1. 确保结果集中存在指定的列。 2. 检查映射配置文件中的属性是否正确。 | | `org.apache.ibatis.cache.CacheException: Cache 'XXXX' not found` | 缓存未找到 | 1. 确保在 XML 配置文件中定义了指定的缓存。 2. 检查缓存名称的拼写和大小写。 | | `org.apache.ibatis.builder.IncompleteElementException: Parsing error was found in mapping` | 映射文件中存在解析错误 | 1. 检查映射文件中的 XML 语法错误。 2. 确保映射文件路径和名称正确。 | | `org.apache.ibatis.builder.BuilderException: Error creating document instance` | 创建 XML 文档实例时出错 | 1. 检查 XML 配置文件的路径和名称是否正确。 2. 确保 XML 文件内容有效。 | | `org.apache.ibatis.session.SqlSessionException: Error committing transaction` | 提交事务时出错 | 1. 确保在事务提交之前没有发生异常。 2. 检查事务管理器的配置是否正确。 | | `org.apache.ibatis.reflection.ReflectionException: Could not set property 'XXXX' of 'XXXX' with value 'XXXX'` | 设置属性值时出错 | 1. 检查属性名称和类型是否正确。 2. 确保属性有对应的 setter 方法。 | | `org.apache.ibatis.executor.ExecutorException: Cannot get the result map` | 获取结果映射失败 | 1. 检查结果映射的名称是否正确。 2. 确保结果映射在 XML 配置文件中定义。 | | `org.apache.ibatis.exceptions.PersistenceException: Error updating database. Cause: java.sql.SQLException: XXXX` | 数据库更新操作失败并引发异常 | 1. 查看异常的详细信息以获取数据库错误信息。 2. 根据异常信息调整 SQL 语句或数据库配置。 | | `org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'XXXX' from result set` | 从结果集获取列失败 | 1. 确保结果集中存在指定的列。 2. 检查映射配置文件中的属性是否正确。 | | `org.apache.ibatis.cache.CacheException: Cache 'XXXX' not found` | 缓存未找到 | 1. 确保在 XML 配置文件中定义了指定的缓存。 2. 检查缓存名称的拼写和大小写。 | | `org.apache.ibatis.builder.IncompleteElementException: Parsing error was found in mapping` | 映射文件中存在解析错误 | 1. 检查映射文件中的 XML 语法错误。 2. 确保映射文件路径和名称正确。 | | `org.apache.ibatis.builder.BuilderException: Error creating document instance` | 创建 XML 文档实例时出错 | 1. 检查 XML 配置文件的路径和名称是否正确。 2. 确保 XML 文件内容有效。 | | `org.apache.ibatis.session.SqlSessionException: Error committing transaction` | 提交事务时出错 | 1. 确保在事务提交之前没有发生异常。 2. 检查事务管理器的配置是否正确。 | | `org.apache.ibatis.reflection.ReflectionException: Could not set property 'XXXX' of 'XXXX' with value 'XXXX'` | 设置属性值时出错 | 1. 检查属性名称和类型是否正确。 2. 确保属性有对应的 setter 方法。 | | `org.apache.ibatis.executor.ExecutorException: Cannot get the result map` | 获取结果映射失败 | 1. 检查结果映射的名称是否正确。 2. 确保结果映射在 XML 配置文件中定义。 | | `org.apache.ibatis.exceptions.PersistenceException: Error updating database. Cause: java.sql.SQLException: XXXX` | 数据库更新操作失败并引发异常 | 1. 查看异常的详细信息以获取数据库错误信息。 2. 根据异常信息调整 SQL 语句或数据库配置。 | | `org.apache.ibatis.binding.BindingException: Type interface 'XXXX' is not known to the MapperRegistry` | Mapper 接口未被注册 | 1. 确保 Mapper 接口被正确注册。 2. 检查 Mapper 接口的路径和名称是否正确。 | | `org.apache.ibatis.binding.BindingException: Could not find a method` | 未找到 Mapper 接口中的方法 | 1. 确保 Mapper 接口中存在指定的方法。 2. 检查方法名称和参数是否正确。 | # Spring # SpringMVC # SpringBoot # Spring-Security

java学习之 MyBatis-day02

## Mapper组件 1. 使用Mapper组件 - 类似DAO,在接口中定义 CRUD 等操作方法。Mapper 组件 = Mapper 接口 + Mapper XML 文件。 - 接口的命名为实体名 + Mapper,一般和其对应 XML 文件放一起 - XML 命名空间及 **namespace="用其对应接口的全限定名"** - Mapper 接口的方法名要和 Mapper XML 文件元素 一致 - 方法的返回类型对应 SQL 元素中定义的 resultType / resultMap 类型; - 方法的参数类型对应 SQL 元素中定义的 paramterType 类型(一般不写)。 ##### Mapper 接口的原理 接口是规范,实质做的实现还是要由实现类对象来做,而这个实现类不需要我们写,实现类对象也不由我们创建,这些都 MyBatis 使用动态代理帮我们做了 提供 Mapper 接口对应 Mapper XML 文件,获取实现类对象的时候传入 Mapper 接口字节码 ## @Param 注解 @Param 注解是 MyBatis 中的一个注解,用于指定方法参数的名称。它的主要作用是解决方法参数名称在编译期被丢失的问题,并且可以让你在 XML 映射文件中更加清晰地引用方法参数。 指定方法参数的名称: Java 中,方法参数的名称在编译后会被丢弃,而只保留参数的类型。这意味着在 XML 映射文件中,你无法通过参数名称来引用方法参数。使用 @Param 注解可以为方法参数指定一个名称,这个名称将用于 XML 映射文件中 ```java public List<User> findUsers(@Param("name") String name, @Param("age") int age); ``` 当传递一个 List 对象或数组对象参数给 MyBatis 时,MyBatis 会自动把它包装到一个 Map 中,此时:List 对象会以 list 作为 key,数组对象会以 array 作为 key,也可以使用注解 @Param 设置 key 名。 ### MyBatis 的 # 和 $ | 特性 | # 占位符 | $ 占位符 | |----------------------|-----------------------------------|--------------------------------| | 参数替换方式 | 安全替换(预编译) | 文本替换(不安全) | | 替换参数 | 使用`?`替代参数 | 直接替换参数值 | | 替换后的值 | 将参数值作为预编译参数 | 将参数值直接嵌入 SQL 文本 | | 防止 SQL 注入攻击 | 是 | 否 | | 支持表名和列名替换 | 否 | 是 | | 字符串拼接 | 不需要手动添加单引号 | 需要手动添加单引号 | | 适用于参数的数据类型 | 通常适用于所有数据类型 | 主要用于处理字符串和 SQL 片段 | | 推荐使用 | 推荐使用 # | 慎用 $,容易受到 SQL 注入攻击的风险 | | 示例 | `WHERE id = #{id}` | `WHERE id = ${id}` | ## 动态SQL 利用动态 SQL 这一特性可以彻底摆脱根据不同条件拼接 SQL 语句的痛苦 - `<where> `标签 `<where>` 标签用于在 SQL 查询中包装多个条件,通常是多个条件之间使用 AND 连接。这个标签会自动处理前置的 WHERE 关键字,并且只在有条件存在时添加 WHERE 关键字。 -`if` 标签 `<if> `标签用于根据条件包含或排除 SQL 查询的一部分。它允许你在运行时检查一个条件,如果条件为真,则包含` <if> `标签内的内容,否则将忽略它。 例如: ```xml <select id="selectUsers" parameterType="User" resultType="User"> SELECT * FROM users <where> <if test="name != null"> AND name = #{name} </if> <if test="age != null"> AND age = #{age} </if> </where> </select> ``` 示例中,< where > 标签包装了两个 < if > 标签,每个 < if > 标签用于检查一个条件是否满足。如果 name 和/或 age 存在,则它们会被包含在 WHERE 子句中,否则 WHERE 子句将为空。 # 多表查询 ## 关系应用 生活中数据很多是存在关系,且存储的数据也能表示出来这种关系 - 保存:页面的数据 ---> 使用 Java 对象封装 ---> 通过 MyBatis ---> 数据库表的数据 - 查询:数据库表的数据 ---> 通过 MyBatis ---> 封装成 Java 对象 ---> 页面展示数据 ### 对象关系分类 - 泛化关系 - 实现关系 - 依赖关系 - 关联关系 - 聚合关系 - 组合关系 ### 关联关系 A 对象依赖 B 对象,并且把 B 作为 A 的一个成员变量,则 A 和 B 存在关联关系。在 UML 中依赖通常使用实线箭头表示。 ##### 分类 1. **按照导航性分** 若通过 A 对象中的某一个属性可以访问到 B 对象,则说 A 可以导航到 B。 - 单向:只能从 A 通过属性导航到 B,B 不能导航到 A。 - 双向:A 可以通过属性导航到 B,B 也可以通过属性导航到 A。 2. **按照多重性分** - 一对一 - 一对多 - 多对一 - 多对多。 ##### 判断关联关系的分类 - 判断都是从对象的实例上面来看的; - 判断关系需要根据对象的属性; - **判断关系必须确定具体需求**。 ### 单向多对一之额外 SQL 查询 单向多对一关系通常用于描述一个实体(多的一端)关联到另一个实体(一的一端)。在MyBatis中,您可以使用额外的SQL查询来检索与多对一关系相关联的数据。 以下是单向多对一关系中使用额外SQL查询的示例: 假设我们有两个实体类:Student 和 Cource ,假设一个学生对应一个课程,即多个学生可能有同一课程。 实体类示例: ```java //课程类 @AllArgsConstructor @Getter @Setter @ToString @NoArgsConstructor public class Course { private Long id; private String Name; } //学生类 @Getter @Setter @AllArgsConstructor @NoArgsConstructor @ToString public class Student { private Long id; private String Name; private Integer Age; private Course course; } ``` 映射文件示例: ```xml <!--课程查询 --> <resultMap id="CourseResultMap" type="Course"> <id property="id" column="ID"/> <result property="Name" column="CouName"/> </resultMap> <select id="selectById" resultMap="CourseResultMap"> select * from course where id=#{id} </select> <!--学生查询 --> <!-- 通过查询过程中的id查询 对应的课程信息 --> <resultMap id="BaseMap" type="Student"> <id property="id" column="id"/> <result property="name" column="StuName"/> <result property="age" column="StuAge"/> <association property="course" select="mybatis.xyz.bycor.mapper.CourseMapper.selectById" column="Cid"> </association> </resultMap> <!-- 查询单个学生的信息 (包括课程信息) --> <select id="selectById" resultMap="BaseMap"> SELECT * FROM student where id=#{id} </select> <!-- 查询所有学生的信息 (包括课程信息) --> <select id="selectAll" resultMap="BaseMap"> SELECT * FROM student </select> <!-- 查询所有学生的信息 (包括课程信息) 方式 2--> <resultMap id="BaseMap2" type="Student" > <id column="id" property="id"/> <result column="StuName" property="name"/> <result column="StuAge" property="age"/> <result column="CouName" property="course.name"/> <result column="Cid" property="course.id"/> </resultMap> <select id="selectAll2" resultMap="BaseMap2"> select s.id,s.StuName,s.StuAge,c.CouName,c.id Cid from student s join course c on c.id = s.Cid </select> <!-- 查询所有学生的信息 (包括课程信息) 方式 3--> <resultMap id="BaseMap3" type="Student"> <id column="id" property="id"/> <result column="StuName" property="name"/> <result column="StuAge" property="age"/> <association property="course" columnPrefix="c_" javaType="Course"> <result column="id" property="id"/> <result column="CouName" property="name"/> </association> </resultMap> <select id="selectAll3" resultMap="BaseMap3"> select s.id,s.StuName,s.StuAge,c.CouName c_CouName,c.id c_id from student s join course c on c.id = s.Cid </select> ``` Java Mapper代码示例: ```java public interface CourseMapper { // 增删 改 查 void delete(Long id); void update(Course course); List<Course> selectAll(); void insert(Course course); Course selectById(Long id); } public interface StudentMapper { // 增删 改 查 void insert(Student student); void delete(Long id); void update(Student student); Student selectById(Long id); List<Student> selectAll(); List<Student> selectAll2(); List<Student> selectAll3(); } ``` Java Test代码示例: ```java @Test public void testMany2OneSelect() { // 查询某个的学生信息包括对应的课程信息 SqlSession sqlSession = MybatisUtil.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); Student student = mapper.selectById(2L); sqlSession.close(); System.out.println(student); } @Test public void testMany2OneSelectAll() { // 查询所有学生信息包括对应的课程信息 SqlSession sqlSession = MybatisUtil.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<Student> students = mapper.selectAll(); sqlSession.close(); students.forEach(System.out::println); } ``` 在上述示例中,我们定义了一个名为 selectAll~~XXX~~ 的查询操作,它用于获取所有学生的信息,包括他们所选的课程信息。这个查询使用了一个自定义的结果映射 BaseMap3,将学生的属性和相关的课程信息进行关联。 下面是这个查询的要点总结: 查询操作:selectAll3,用于获取所有学生的信息以及他们所选的课程信息。 结果映射:BaseMap3,自定义结果映射,用于将查询结果映射到 Student 类型的对象上。 查询语句:SQL 查询语句联接了 student 表和 course 表,通过学生表的外键关联了相关的课程信息。 结果映射配置:在结果映射中,我们定义了学生属性的映射,以及关联的课程属性的映射。这样,查询结果将自动映射到 Student 对象的属性中,包括学生的基本信息和所选课程的信息。 通过这种方式,我们可以一次性获取学生和他们所选课程的信息,无需手动处理查询结果集的关联,提高了代码的可读性和查询效率。这是 MyBatis 中处理多表关联查询的一种常见方法。

java学习之 MyBatis-day01

# 初识框架 **框架是一种经过校验、具有一定功能的半成品软件**. - **经过校验**:指框架本身经过测试,且框架自身所具有的功能已经实现 - **具有一定功能**:指框架可以完成特定的功能,不同的框架功能不同 - **半成品软件**:指框架自身是一个软件,但是该软件无法直接运行,需要配合其他的程序才可以完成指定的工作. ### 程序架构 一.分层 ![三层架构.png](https://pic.code-nav.cn/post_picture/1673111457186713601/DHmK4tQ0-三层架构.png) 二.架构分工 ![image.png](https://pic.code-nav.cn/post_picture/1673111457186713601/hdTMx1fM-image.png) 三.架构职责 ![三层架构职责.png](https://pic.code-nav.cn/post_picture/1673111457186713601/ouLtMzB8-三层架构职责.png) # MyBatis 基础 MyBatis 是一款优秀的**持久层框架**,它支持定制化 SQL、存储过程以及高级映射。**MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集**。 ## 使用流程 ![image-20200530114424946.png](https://pic.code-nav.cn/post_picture/1673111457186713601/TCQxe3T1-image-20200530114424946.png) ## 准备环境 `添加项目需要的 jar 包` 1. lombok-1.18.20.jar Lombok,自动生成 getter/setter/toString 等方法 使用的前提是已经在 idea 中安装了 lombok 插件 2. mysql-connector-java-5.1.26-bin.jar MySQL 数据库的 JDBC 驱动包,访问 MySQL 必须导入备 jar 包 3. mybatis-3.4.5.jar MyBatis 框架的核心 jar 包 4. 创建操作的表 5. 根据表结构创建实体类 4. **mybatis 主配置文件: mybatis-config.xml** 1. 在项目的 resources(resources root)下创建 mybatis-config.xml 配置文件 6. 拷贝 xml 的约束 ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> ``` 7. 添加环境配置(事务管理器 / 连接池 / 映射文件) ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="dev"> <environment id="dev"> <!-- MyBatis 内置的事务管理器 JDBC:org.apache.ibatis.transaction.jdbc.JdbcTransaction的别名 --> <transactionManager type="JDBC"/> <!-- MyBatis 内置的连接池 POOLED:org.apache.ibatis.datasource.pooled.PooledDataSource的别名 --> <dataSource type="POOLED"> <!-- driver:这是POOLED连接池对象的驱动类的属性名, Druid连接池对象的驱动类属性名是driverClassName --> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///mybatis"/> <property name="username" value="root"/> <property name="password" value="admin"/> </dataSource> </environment> </environments> <mappers> <mapper resource="xxx/mapper/UserMapper.xml"/> </mappers> </configuration> ``` 8. db.properties配置文件 在主配置文件中配置的内容较多, 其中包括我们修改频率较高的数据库连接信息(driver/url/username/password)等,我们可以在修改这些信息的过程中误改或者误删到其他的配置,为了解决这个问题,我们仍然是将这些信息配置到db.propertie 配置文件中,然后再合并到主配置文件即可,如下: ```properties driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis username=root password=admin ``` mybatis-config.xml ```xml <configuration> <!-- 关联db.properties:为了把连接数据库的信息单独放到一个配置文件 --> <properties resource="db.properties" /> </configuration> ``` 9. mapper 映射文件: UserMapper.xml mybatis中,访问数据库的SQL语句是编写在mapper配置文件中的,程序员按照这个文件约定的格式进行配置即可在包 cn.wolfcode.day09.mapper 中创建配置文件: UserMapper.xml 拷贝下面的约束信息到配置文件中 ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> ``` 在配置文件中添加 SQL 语句 ```xml <!-- 一个项目可以操作多张表 每张表都需要一个mapper配置文件来编写SQL语句 每条SQL语句都需要有一个唯一的标识 这个唯一的标识由 namespace + sqlid 组成 使用下面的namespace+sqlid就得到了保存用户信息的唯一标识: cn.wolfcode.mybatis.mapper.UserMapper.insert 接下来,我们就可以使用上面的标识找到这条SQL语句了 --> <mapper namespace="cn.wolfcode.mybatis.mapper.UserMapper"> <insert id="insert"> insert into user(name,age,salary,hiredate) values(#{name}, #{age}, #{salary}, #{hiredate}) </insert> </mapper> ``` **注意**: 一定记得在 mybatis-config.xml 配置文件中关联映射文件 ```xml <mappers> <!-- 这里是mapper文件的路径,所以使用/分割 --> <mapper resource="xxx/mybatis/mapper/UserMapper.xml"/> </mappers> ``` ## 2.4_MyBatis 执行流程(理解) 1. 加载主配置文件 (mybatis-config.xml & XxxMapper.xml) 到内存中,将数据封装成对象 Configuration/Environment/TransactionManager/DataSource/Statement Collection等 2. 通过操作拿到访问数据库的基本信息,根据这些数据创建 SqlSessionFactory 对象 3. 从 SqlSessionFactory 对象中获取到 SqlSession 对象,然后执行SQL 4. INSERT INTO user(name,age,salary) VALUES(#{name},#{age},#{salary}) 被翻译成 INSERT INTO user(name,age,salary) VALUES(?, ?, ?) 5. 使用 PreparedStatement 来执行指定的SQL 从传递进来的 User 对象中依次获取到 name/age/salary 这些属性的值 这里需要使用到内省机制来访问对象中的属性 **注:** 在加载完当前映射文件之后,会将SQL中的 #{} **OGNL表达式**翻译成对应的占位符? # 3_获取自动生成的主键 在开发中,如果需要获取到数据库中自动生成的主键,那么使用 MyBatis 应该如何实现呢? ```xml <insert id="insert" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> insert into user(name,age,salary,hiredate) values(#{name}, #{age}, #{salary}, #{hiredate}) </insert> ``` useGeneratedKeys: 是否要获取自动生成的主键 keyColumn: 表中的主键列 keyProperty: 主键列对应的属性 表示从获取哪个列的值封装到哪个属性中 # 4_日志管理 (掌握) 在持久层的开发过程中,我们程序员需要随时观察SQL的执行情况,如果sql有问题,我们能够及时发现 所以,如果能够在控制台中将我们执行的 SQL 全部打印出来,那么就可以方便的观察SQL的相关问题 配置日志文件监控 MyBatis 的运行. 1. 将日志相关的 jar 包添加到项目中 ![image-20200427083931199.png](https://pic.code-nav.cn/post_picture/1673111457186713601/qN3EneWV-image-20200427083931199.png) 2. 在 resources(resources root)中创建配置文件, log4j.properties ,添加下面的内容(直接拷贝) ```properties # Global logging configuration log4j.rootLogger=ERROR, stdout # 配置要打印日志的包 log4j.logger.xxx=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n ``` 3. 将配置中的 包路径修改为项目中对应的路径,我们这里可以使用: cn.wolfcode.mybatis 到此,我们每执行一条 SQL, 都会在控制台中打印出来,这非常有助于我们对 SQL 的分析,特别是 SQL 不正确的时候 # 7_类型别名 在查询操作中, 我们需要使用 resultType 属性指定数据封装的类型, 这里的值是类型的全限定名, 每次都写的话比较麻烦,为了简化这里的配置,我们可以在主配置文件(mybatis-config.xml)中对指定的类型做别名的配置 ```xml <!-- 为指定包中的类来生成别名,默认是类的简单名称 --> <typeAliases> <package name="包名"/> </typeAliases> ``` 如此,我们在查询的SQL中, 使用类的全限定名和使用别名是等价的 修改前: ```xml <select id="selectAll" resultType="XXX.domain.User"> select * from user </select> ```

java学习之- JDBC-day01

# JDBC ### 持久化 **持久化是指将数据保存在非易失性存储介质中,以便在程序结束后或系统重启后能够继续存在**。在软件开发中,持久化通常用于将内存中的数据存储到数据库、文件系统等存储介质中,以保证数据的长期存储和可恢复性。 ### JDBC JDBC(Java Database Connectivity) 是 **Java 提供的用于与数据库进行交互的标准接口**。它允许 Java 应用程序通过 SQL 查询和更新来访问和操作数据库。JDBC 提供了一套标准的 API,使得开发人员能够在不同的数据库系统之间切换而无需更改大部分代码。 #### DAO 思想(数据访问对象) **DAO(Data Access Object) 是一种设计模式**,用于将数据访问逻辑从业务逻辑中分离出来。DAO 的核心思想是将对数据库的操作抽象成一组接口和实现,以提供更加灵活、可维护和可测试的数据访问方式。通过使用 DAO,业务逻辑可以专注于业务操作,而不用关心底层数据库的细节。 ##### DAO 规范 + DAO 接口 : 表示对某个模型的 CRUD 操作做规范,以 I 开头,interface + 标准:**IXxxDAO** + 例: IEmployeeDAO/IStudentDAO + DAO 实现类: 表示对某个 DAO 接口的实现 + 标准:**XxxDAOImpl** + 例:EmployeeDAOImpl/StudentDAOImpl + DAO 测试类: 测试 DAO 组件中的所有方法 (测试先行) + 标准:**XxxDAOTest**: XxxDAO 组件的测试类, + 例:EmployeeDAOTest,StudentDAOTest ### JDBC 使用流程 #### 开发口诀 `贾琏欲执事` + 1. **加**载注册驱动. + 2. 获取**连**接对象. + 3. 创建/获取**语**句执行对象. + 4. **执**行SQL语句. + 5. **释**放资源. #### ##### DriverManager 类 + 全限定名获取DriverManager Class 对象 + 通过getConnection() 方法获取链接对象 ##### Connection 类 Connection :关系型数据库连接对象,相当于 Java 程序和数据库的通信桥梁 1. 获取语句执行对象 + 获取静态语句执行对象: Statement createStatement(); + 获取预编译语句执行对象: PreparedStatement prepareStatement(String sql); 2. 释放资源 + 关闭连接对象: void close(); 3. 事务 ##### Statement 类 1. 执行 DML / DDL 语句 : int executeUpdate(String sql); + 返回值 : DML 受影响的行数,DDL 则返回 0 + 参数:insert、update、delete、create、drop 语句 2. 执行 DQL 语句:ResultSet executeQuery(String sql); + 返回值:执行查询之后的结果数据 + 参数:select 语句 3. 释放资源 + 关闭 Statement 对象 :void close(); ### 根据 DAO 规范搭建项目 #### 步骤 1. 创建项目 2. 导入数据库驱动包 3. 创建表和模型包以及模型对象 4. 创建 DAO 包和 DAO 接口,设计 DAO 接口方法 5. 创建 DAO 实现包,实现 DAO 接口 6. 创建测试目录,生成测试类和方法 7. 书写实现,实现一个方法测试一个方法并且测试通过 假设你要搭建一个学生信息管理系统,你可以按照以下步骤来创建项目: 1. **创建项目结构:** 创建一个项目文件夹,然后在其中创建以下目录结构: ```java - src - main - java - com - yourcompany - dao -impl - domain - util - test - resources ``` 1. **创建 Model 类:** 在 `model` 包中创建一个名为 `Student` 的类,表示学生模型。这个类将包含学生的属性,如 id、name、age 和 email。 ```java package com.yourcompany.model; public class Student { private long id; private String name; private int age; private String email; // 构造方法、getter 和 setter 省略 } ``` 1. **创建 DAO 接口:** 在 `dao` 包中创建一个名为 `IStudentDAO` 的接口,定义各种与学生信息相关的数据库操作方法。 ```java package com.yourcompany.dao; import com.yourcompany.model.Student; public interface IStudentDAO { Student selectById(long id); List<Student> selectAll(); void insert(Student student); void update(Student student); void delete(long id); } ``` 1. **创建 DAO 实现类:** 在 `dao` 包中创建一个名为 `StudentDAOimpl` 的类,实现 `StudentDAO` 接口。在这个类中,你可以使用 JDBC 进行数据库操作。 ```java package com.yourcompany.dao; import com.yourcompany.model.Student; import com.yourcompany.util.JDBCUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; public class StudentDAOimpl implements StudentDAO { // 实现接口中的方法,例如 selectById、selectAll、insert 等 } ``` 1. **创建 JDBCUtil 工具类:** 在 `util` 包中创建一个名为 `JDBCUtil` 的类,用于提供数据库连接、关闭资源等方法。 ```java package com.yourcompany.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class JDBCUtil { public static Connection getConnection() throws SQLException { // 获取数据库连接的代码 } public static void close(Connection conn, PreparedStatement ps, ResultSet rs) { // 关闭资源的代码 } } ``` #### JDBCUtil 在 DAO 的实现过程中,发现释放资源的代码非常恶心,而且还需要反复编写,这种代码我们通常可以抽取到工具类中: JDBCUtil ```java // JDBCUtil.java public static void close(Connection conn, Statement pst) { close(conn,pst,null); } // 释放资源 public static void close(Connection conn, Statement pst, ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (Exception e) { e.printStackTrace(); } // 释放资源 try { if (pst != null) { pst.close(); } } catch (Exception e) { e.printStackTrace(); } try { if (conn != null) { conn.close(); } } catch (Exception e) { e.printStackTrace(); } } ```

下载 APP